﻿using System;
using System.Linq.Expressions;
using System.Reflection;
using MyLib.Data;

namespace MyLib.Web {
	/// <summary>
	/// 
	/// </summary>
	public abstract class MyUserControl : System.Web.UI.UserControl {
		private const string CONST_CODE_FILE_NAME = @"~/ConstSysCode.xml";

		/// <summary>
		/// 
		/// </summary>
		protected log4net.ILog m_logger;

		/// <summary>
		/// 
		/// </summary>
		protected MyUserControl() {
			m_logger = log4net.LogManager.GetLogger(GetType());
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="errorMessage"></param>
		protected void AddError(string errorMessage) {
			var p = Page as MyPage;
			if (p != null)
				p.AddError(errorMessage);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="format"></param>
		/// <param name="args"></param>
		protected void AddError(string format, params object[] args) {
			var p = Page as MyPage;
			if (p != null)
				p.AddError(format, args);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="warningMessage"></param>
		protected void AddWarning(string warningMessage) {
			var p = Page as MyPage;
			if (p != null)
				p.AddWarning(warningMessage);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="format"></param>
		/// <param name="args"></param>
		protected void AddWarning(string format, params object[] args) {
			var p = Page as MyPage;
			if (p != null)
				p.AddWarning(format, args);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="inforMessage"></param>
		protected void AddInformation(string inforMessage) {
			var p = Page as MyPage;
			if (p != null)
				p.AddInformation(inforMessage);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="format"></param>
		/// <param name="args"></param>
		protected void AddInformation(string format, params object[] args) {
			var p = Page as MyPage;
			if (p != null)
				p.AddInformation(format, args);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="categoryId"></param>
		/// <param name="value"></param>
		/// <returns></returns>
		protected string GetCodeTextFromValue(int categoryId, object value) {
			return GetCodeTextFromValue(CONST_CODE_FILE_NAME, categoryId, value);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="codeFileName"></param>
		/// <param name="categoryId"></param>
		/// <param name="value"></param>
		/// <returns></returns>
		protected string GetCodeTextFromValue(string codeFileName, int categoryId, object value) {
			System.Diagnostics.Debug.Assert(codeFileName != null);

			codeFileName = codeFileName.Trim();

			if (!codeFileName.StartsWith("~/") && !System.IO.Path.IsPathRooted(codeFileName)) {
				codeFileName = "~/" + codeFileName;
			}

			var cp = new CodeProvider(Context.Request.MapPath(codeFileName), new WebCacheProvider(Context));
			return cp.GetTextFromValue(categoryId, value);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="action"></param>
		protected void ExecuteSafely(Action action) {
			ExecuteSafely(
				action,
				(ex) => {
					AddError(ex.FormatMessage());
				});
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="action"></param>
		/// <param name="exceptionHandler"></param>
		protected void ExecuteSafely(Action action, Action<Exception> exceptionHandler) {
			try {
				action();
			} catch (ApplicationException ex) {
				if (m_logger.IsDebugEnabled) {
					m_logger.Debug("Failed to execute action.", ex);
				}

				exceptionHandler(ex);
			}
		}

		/// <summary>
		/// 
		/// </summary>
		private static readonly PropertyInfo m_viewStatePropertyInfo = typeof(System.Web.UI.Page)
			.GetProperty("ViewState", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);

		private System.Web.UI.StateBag m_cachedPageViewState = null;

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		protected System.Web.UI.StateBag PageViewState {
			get {
				if (m_cachedPageViewState == null) {
					var p0 = Expression.Parameter(typeof(System.Web.UI.Page));
					var exp = Expression.Lambda<Func<System.Web.UI.Page, System.Web.UI.StateBag>>(
						Expression.Property(
							p0,
							m_viewStatePropertyInfo),
						p0).Compile();

					m_cachedPageViewState = exp(Page);
				}

				return m_cachedPageViewState;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="group"></param>
		/// <returns></returns>
		protected string[] GetCheckedValues(string group) {
			System.Diagnostics.Debug.Assert(!string.IsNullOrEmpty(group));

			var checkedValues = this.Request[group];
			if (string.IsNullOrEmpty(checkedValues))
				return new string[0];
			else
				return checkedValues.Split(',');
		}
	} // end of MyUserControl.
}
